package com.dw.controller;

import com.dw.entity.Product;
import com.dw.model.message.TestMessage;
import com.dw.service.ProductService;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.cloud.stream.function.StreamBridge;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
//import org.springframework.messaging.Message;
//import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
@RequestMapping("/product")
public class ProductController {
    @Autowired
    private ProductService productService;

    @Autowired
    private RedisTemplate<String , Object> redisTemplate;

    @Autowired
    RedissonClient redissonClient;

    public static final String BINDING_NAME = "user-output";

    public static final String PRODUCT_CHANNEL = "product-output";


//    @Autowired
//    StreamBridge streamBridge;

    @GetMapping("/reduceProduct")
    public int reduceProduct() throws InterruptedException {  //http://localhost:9092/product/reduceProduct
        int i = productService.reduceProduct(1L);
        return i;
    }

//    @GetMapping("/sendmq")  //product/sendmq
//    public String sendmq(){
//        TestMessage msg = TestMessage.builder().msgId(1).build();
//        Message<TestMessage> message= MessageBuilder.withPayload(msg).setHeader("messageId",UUID.randomUUID()).build();
//        log.info("发送消息：{}",message);
//        streamBridge.send(BINDING_NAME,message);
//        return "send ok...";
//    }
//
//    @GetMapping("/sendmqDelay")
//    public String sendmqDelay() {
//        TestMessage msg = TestMessage.builder().msgId(1).build();
//        // 构建消息并设置延迟级别
//        Message<TestMessage> message = MessageBuilder.withPayload(msg)
//                .setHeader("DELAY", 3) // 动态设置延迟级别
//                .build();
//
//        log.info("发送延迟消息，延迟级别：{}", 2);
//        streamBridge.send(PRODUCT_CHANNEL, message);
//        return "发送 延迟等级 3 的MQ ok...";
//    }

    //无锁
    @GetMapping("/nolock_reduceProduct")
    public String  nolock_reduceProduct() {  //http://localhost:9092/product/reduceProduct
        Product product = productService.getById(1);
        if(product.getProductNum()>0) {
            int i = productService.reduceProduct(1L);
            if(i>0)
                log.info("扣减成功,商品数量:{}",product.getProductNum());
        }
        return "执行成功";
    }


    //同步锁
    @GetMapping("/syn_reduceProduct")
    public String  syn_reduceProduct() throws InterruptedException {  //http://localhost:9092/product/syn_reduceProduct
        synchronized ("lock"){
            Product product = productService.getById(1);
            if(product.getProductNum()>0) {
                int i = productService.reduceProduct(1L);
                if(i>0) {
                    log.info("扣减成功,商品数量:{}", product.getProductNum());
                    return "执行成功";
                }else{
                    log.info("扣减失败,商品数量:{}", product.getProductNum());
                }
            }
        }
        return "扣减失败";
    }

    //redisson分布式锁
    @GetMapping("/rds_reduceProduct")
    public String  rds_reduceProduct() throws InterruptedException {  //http://localhost:9092/product/reduceProduct
        RLock lock = redissonClient.getLock("mylock");
        lock.lock(500, TimeUnit.MILLISECONDS);
        Product product = productService.getById(1);
        if(product.getProductNum()>0) {
            int i = productService.reduceProduct(1L);
            if(i>0) {
                log.info("扣减成功,商品数量:{}", product.getProductNum());
            }
        }
        lock.unlock();
        return "...";
    }



    //test redis
    @GetMapping("/redistest")
    public int redistest() throws InterruptedException {  //http://localhost:9092/product/reduceProduct
        ValueOperations<String, Object> opsForValue = redisTemplate.opsForValue();
        RLock lock = redissonClient.getLock("mylock");
        lock.lock();
        int num = 0;
        if(opsForValue.get("num")==null){
            num = 1;
        }else{
            num = (int)opsForValue.get("num"); //
            num ++;
        }
        opsForValue.set("num",num);
        lock.unlock();
        System.out.println(num);
        return num;
    }

//    @GetMapping("/rds_reduceProduct")
//    public String  rds_reduceProduct() throws InterruptedException {  //http://localhost:9092/product/reduceProduct
//        RLock lock = redisson.getLock("mylock");
//        lock.lock();
//        Product product = productService.getById(1);
//        if(product.getProductNum()>0) {
//            int i = productService.reduceProduct(1L);
//            if(i>0) {
//                log.info("扣减成功,商品数量:{}", product.getProductNum());
//                return "执行成功";
//            }
//        }
//        lock.unlock();
//        return "扣减失败";
//    }



}
